"""
主窗口模块
"""

import tkinter as tk
from tkinter import ttk, filedialog, messagebox
from typing import Optional, Set
from pathlib import Path
import threading
from PIL import Image

from ..config import ConfigManager
from ..utils.logger import Logger
from ..utils.async_processor import AsyncProcessor, Task, ProgressTracker
from ..core.pdf_processor import PDFProcessor
from ..core.ppt_converter import PPTConverter
from ..core.file_manager import FileManager
from .components.thumbnail_viewer import ThumbnailViewer
from .components.progress_dialog import ProgressDialog, TaskProgressDialog


class MainWindow:
    """主窗口类"""
    
    def __init__(self, config: ConfigManager, logger: Logger):
        self.config = config
        self.logger = logger
        
        # 初始化核心组件
        self.pdf_processor = PDFProcessor(logger)
        self.ppt_converter = PPTConverter(logger)
        self.file_manager = FileManager(logger)
        self.async_processor = AsyncProcessor(config.processing.max_concurrent_operations)
        
        # 初始化GUI
        self.root = tk.Tk()
        self.thumbnail_viewer = None
        self.current_pdf_path = None
        self.current_ppt_path = None  # 当前PPT文件路径
        self.temp_pdf_path = None     # 临时PDF文件路径
        self.selected_pages: Set[int] = set()
        self.current_file_type = None  # 'pdf' 或 'ppt'
        
        self._setup_window()
        self._create_widgets()
        self._bind_events()
        
        self.logger.info("主窗口初始化完成")
    
    def _setup_window(self):
        """设置主窗口"""
        self.root.title("文件转换器 v2.0")
        
        # 设置窗口大小
        width, height = self.config.ui.window_size
        self.root.geometry(f"{width}x{height}")
        
        # 设置最小尺寸
        min_width, min_height = self.config.ui.window_min_size
        self.root.minsize(min_width, min_height)
        
        # 设置图标（如果有的话）
        try:
            # self.root.iconbitmap("icon.ico")
            pass
        except:
            pass
    
    def _create_widgets(self):
        """创建界面组件"""
        # 创建主框架
        main_frame = ttk.Frame(self.root)
        main_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
        
        # 创建工具栏
        self._create_toolbar(main_frame)
        
        # 创建主内容区域
        self._create_main_area(main_frame)
        
        # 创建状态栏
        self._create_status_bar(main_frame)
    
    def _create_toolbar(self, parent):
        """创建工具栏"""
        self.toolbar_frame = ttk.Frame(parent)  # 保存引用以便添加进度条
        self.toolbar_frame.pack(fill=tk.X, pady=(0, 5))
        
        # 文件操作组
        file_group = ttk.LabelFrame(self.toolbar_frame, text="文件操作", padding="5")
        file_group.pack(side=tk.LEFT, padx=(0, 5))

        ttk.Button(file_group, text="打开PDF", command=self._open_pdf).pack(side=tk.LEFT, padx=2)

        # PPT功能按钮组
        ppt_btn = ttk.Button(file_group, text="打开PPT预览", command=self._open_ppt_preview)
        if not self.ppt_converter.is_available:
            ppt_btn.config(state=tk.DISABLED)
        ppt_btn.pack(side=tk.LEFT, padx=2)

        ppt_convert_btn = ttk.Button(file_group, text="PPT转PDF", command=self._convert_ppt)
        if not self.ppt_converter.is_available:
            ppt_convert_btn.config(state=tk.DISABLED)
        ppt_convert_btn.pack(side=tk.LEFT, padx=2)

        # 页面操作组
        page_group = ttk.LabelFrame(self.toolbar_frame, text="页面操作", padding="5")
        page_group.pack(side=tk.LEFT, padx=(0, 5))

        ttk.Button(page_group, text="全选", command=self._select_all).pack(side=tk.LEFT, padx=2)
        ttk.Button(page_group, text="反选", command=self._invert_selection).pack(side=tk.LEFT, padx=2)
        ttk.Button(page_group, text="清除选择", command=self._clear_selection).pack(side=tk.LEFT, padx=2)

        # 导出操作组
        export_group = ttk.LabelFrame(self.toolbar_frame, text="导出", padding="5")
        export_group.pack(side=tk.LEFT, padx=(0, 5))

        ttk.Button(export_group, text="合并导出", command=self._export_merged).pack(side=tk.LEFT, padx=2)
        ttk.Button(export_group, text="分页导出", command=self._export_separate).pack(side=tk.LEFT, padx=2)
    
    def _create_main_area(self, parent):
        """创建主内容区域"""
        # 创建缩略图查看器
        self.thumbnail_viewer = ThumbnailViewer(parent, self.logger)
        self.thumbnail_viewer.pack(fill=tk.BOTH, expand=True)
        
        # 设置选择回调
        self.thumbnail_viewer.set_selection_callback(self._on_selection_changed)
    
    def _create_status_bar(self, parent):
        """创建状态栏"""
        status_frame = ttk.Frame(parent)
        status_frame.pack(fill=tk.X, pady=(5, 0))
        
        # 状态标签
        self.status_label = ttk.Label(status_frame, text="就绪")
        self.status_label.pack(side=tk.LEFT)
        
        # 页面信息标签
        self.page_info_label = ttk.Label(status_frame, text="")
        self.page_info_label.pack(side=tk.RIGHT)
    
    def _bind_events(self):
        """绑定事件"""
        self.root.protocol("WM_DELETE_WINDOW", self._on_closing)
        
        # 保存窗口大小变化
        self.root.bind("<Configure>", self._on_window_configure)
    
    def _on_window_configure(self, event):
        """处理窗口配置变化"""
        if event.widget == self.root:
            # 保存窗口大小
            self.config.ui.window_size = (self.root.winfo_width(), self.root.winfo_height())
            if self.config.processing.auto_save_config:
                self.config.save_config()
    
    def _on_selection_changed(self, selected_pages: Set[int]):
        """处理选择变化"""
        self.selected_pages = selected_pages
        
        # 更新状态栏
        if selected_pages:
            self.page_info_label.config(text=f"已选择 {len(selected_pages)} 页")
        else:
            self.page_info_label.config(text="")
    
    def _open_pdf(self):
        """打开PDF文件，参考原始实现的同步方式"""
        file_path = filedialog.askopenfilename(
            title="选择PDF文件",
            filetypes=[("PDF文件", "*.pdf"), ("所有文件", "*.*")]
        )

        if not file_path:
            return

        try:
            # 参考原始实现：同步加载，避免异步回调问题
            self.status_label.config(text="正在加载PDF...")
            self.root.update()

            # 加载PDF文档
            success = self.pdf_processor.load_document(file_path)
            if not success:
                raise Exception("PDF加载失败")

            # 生成缩略图（同步方式，带进度更新）
            self._generate_thumbnails_sync()

            # 更新状态
            self.current_pdf_path = file_path
            self.current_ppt_path = None
            self.current_file_type = 'pdf'
            filename = Path(file_path).name
            self.status_label.config(text=f"已加载: {filename}")
            self.page_info_label.config(text=f"共 {self.pdf_processor.page_count} 页")

            self.logger.info(f"PDF加载完成: {self.pdf_processor.page_count} 页")

        except Exception as e:
            self.logger.error(f"PDF加载失败: {e}")
            messagebox.showerror("错误", f"PDF加载失败:\n{e}")
            self.status_label.config(text="加载失败")

    def _generate_thumbnails_sync(self):
        """同步生成缩略图，参考原始实现"""
        if not self.pdf_processor.current_document:
            return

        # 清空现有缩略图
        self.thumbnail_viewer.clear()

        # 创建临时进度条
        progress_frame = ttk.Frame(self.root)
        progress_frame.pack(fill=tk.X, padx=5, pady=2)

        progress_label = ttk.Label(progress_frame, text="生成缩略图...")
        progress_label.pack(side=tk.LEFT)

        progress_bar = ttk.Progressbar(
            progress_frame,
            orient=tk.HORIZONTAL,
            maximum=self.pdf_processor.page_count
        )
        progress_bar.pack(side=tk.RIGHT, fill=tk.X, expand=True, padx=(10, 0))

        self.root.update()

        try:
            thumbnails = []
            size = (self.config.ui.thumbnail_width, int(self.config.ui.thumbnail_width * 1.414))

            # 参考原始实现：在主线程中生成缩略图并更新进度
            for page_num in range(self.pdf_processor.page_count):
                try:
                    thumbnail = self.pdf_processor.generate_thumbnail(page_num, size)
                    thumbnails.append(thumbnail)

                    # 更新进度
                    progress_bar['value'] = page_num + 1
                    progress_label.config(text=f"生成缩略图... {page_num + 1}/{self.pdf_processor.page_count}")
                    self.root.update()

                except Exception as e:
                    self.logger.warning(f"跳过页面 {page_num + 1}: {e}")
                    # 创建空白缩略图
                    blank_img = Image.new('RGB', size, color='white')
                    thumbnails.append(blank_img)

            # 设置缩略图到查看器
            self.thumbnail_viewer.set_thumbnails(thumbnails)

        finally:
            # 移除进度条
            progress_frame.destroy()
    

    
    def _convert_ppt(self):
        """转换PPT到PDF，参考原始实现的同步方式"""
        if not self.ppt_converter.is_available:
            messagebox.showerror("错误", "PPT转换功能不可用，请安装pywin32")
            return

        # 选择PPT文件
        input_path = filedialog.askopenfilename(
            title="选择PPT文件",
            filetypes=[("PowerPoint文件", "*.ppt *.pptx"), ("所有文件", "*.*")]
        )

        if not input_path:
            return

        # 选择输出目录
        output_dir = filedialog.askdirectory(title="选择输出目录")
        if not output_dir:
            return

        # 生成输出文件路径
        input_file = Path(input_path)
        output_path = Path(output_dir) / f"{input_file.stem}.pdf"

        # 参考原始实现：创建进度提示窗口
        progress_window = tk.Toplevel(self.root)
        progress_window.title("转换中...")
        progress_window.geometry("400x120")
        progress_window.resizable(False, False)

        # 居中显示
        progress_window.transient(self.root)
        progress_window.grab_set()

        # 创建进度内容
        main_frame = ttk.Frame(progress_window, padding="20")
        main_frame.pack(fill=tk.BOTH, expand=True)

        ttk.Label(main_frame, text=f"正在转换PPT文件: {input_file.name}").pack(pady=(0, 10))
        ttk.Label(main_frame, text="请稍候，转换完成后会自动提示...").pack(pady=(0, 10))

        # 不确定进度条
        progress_bar = ttk.Progressbar(main_frame, mode='indeterminate', length=350)
        progress_bar.pack()
        progress_bar.start()

        # 居中窗口
        self._center_window(progress_window)
        self.root.update()

        # 参考原始实现：使用线程但简化处理
        def conversion_thread():
            try:
                # 直接调用转换方法
                success = self.ppt_converter.convert_to_pdf(input_path, output_path)

                if success:
                    self.root.after(0, lambda: self._handle_ppt_converted_with_progress(output_path, progress_window))
                else:
                    self.root.after(0, lambda: self._handle_ppt_convert_error_with_progress("转换失败", progress_window))

            except Exception as e:
                self.root.after(0, lambda: self._handle_ppt_convert_error_with_progress(str(e), progress_window))

        # 启动转换线程
        threading.Thread(target=conversion_thread, daemon=True).start()

    def _center_window(self, window):
        """居中窗口"""
        window.update_idletasks()

        # 获取窗口尺寸
        window_width = window.winfo_width()
        window_height = window.winfo_height()

        # 获取屏幕尺寸
        screen_width = window.winfo_screenwidth()
        screen_height = window.winfo_screenheight()

        # 计算居中位置
        x = (screen_width - window_width) // 2
        y = (screen_height - window_height) // 2

        window.geometry(f"{window_width}x{window_height}+{x}+{y}")

    def _handle_ppt_converted_with_progress(self, output_path, progress_window):
        """处理PPT转换完成（带进度窗口）"""
        # 关闭进度窗口
        progress_window.destroy()

        self.logger.info(f"PPT转换完成: {output_path}")
        messagebox.showinfo("转换成功", f"文件已成功转换至:\n{output_path}")

        # 询问是否打开转换后的PDF
        if messagebox.askyesno("打开文件", "是否要打开转换后的PDF文件？"):
            self._load_converted_pdf_sync(str(output_path))

    def _handle_ppt_convert_error_with_progress(self, error, progress_window):
        """处理PPT转换错误（带进度窗口）"""
        # 关闭进度窗口
        progress_window.destroy()

        self.logger.error(f"PPT转换失败: {error}")
        messagebox.showerror("转换失败", f"PPT转换失败:\n{error}")

    def _load_converted_pdf_sync(self, file_path: str):
        """同步加载转换后的PDF"""
        try:
            self.status_label.config(text="正在加载转换后的PDF...")
            self.root.update()

            # 加载PDF文档
            success = self.pdf_processor.load_document(file_path)
            if not success:
                raise Exception("PDF加载失败")

            # 生成缩略图
            self._generate_thumbnails_sync()

            # 更新状态
            self.current_pdf_path = file_path
            filename = Path(file_path).name
            self.status_label.config(text=f"已加载: {filename}")
            self.page_info_label.config(text=f"共 {self.pdf_processor.page_count} 页")

        except Exception as e:
            self.logger.error(f"加载转换后的PDF失败: {e}")
            messagebox.showerror("错误", f"加载PDF失败:\n{e}")

    def _open_ppt_preview(self):
        """打开PPT文件并显示预览（新方案：先转PDF再预览）"""
        if not self.ppt_converter.is_available:
            messagebox.showerror("错误", "PPT转换功能不可用，请安装pywin32")
            return

        # 选择PPT文件
        file_path = filedialog.askopenfilename(
            title="选择PPT文件",
            filetypes=[("PowerPoint文件", "*.ppt *.pptx"), ("所有文件", "*.*")]
        )

        if not file_path:
            return

        # 清理之前的临时文件
        self._cleanup_temp_files()

        # 创建进度窗口
        progress_window = tk.Toplevel(self.root)
        progress_window.title("加载PPT预览")
        progress_window.geometry("400x120")
        progress_window.resizable(False, False)
        progress_window.transient(self.root)
        progress_window.grab_set()

        # 创建进度内容
        main_frame = ttk.Frame(progress_window, padding="20")
        main_frame.pack(fill=tk.BOTH, expand=True)

        filename = Path(file_path).name
        ttk.Label(main_frame, text=f"正在转换PPT为预览格式: {filename}").pack(pady=(0, 10))
        ttk.Label(main_frame, text="请稍候，转换完成后将显示预览...").pack(pady=(0, 10))

        # 不确定进度条
        progress_bar = ttk.Progressbar(main_frame, mode='indeterminate', length=350)
        progress_bar.pack()
        progress_bar.start()

        # 居中窗口
        self._center_window(progress_window)
        self.root.update()

        # 在线程中执行转换
        def conversion_thread():
            try:
                # 步骤1: 将PPT完整转换为临时PDF
                temp_pdf_path = self.ppt_converter.convert_ppt_to_temp_pdf(file_path)

                # 步骤2: 使用PDF处理器加载临时PDF
                self.root.after(0, lambda: self._load_temp_pdf_and_show_preview(
                    file_path, temp_pdf_path, progress_window
                ))

            except Exception as e:
                self.root.after(0, lambda: self._handle_ppt_preview_error(str(e), progress_window))

        # 启动转换线程
        threading.Thread(target=conversion_thread, daemon=True).start()

    def _load_temp_pdf_and_show_preview(self, ppt_path: str, temp_pdf_path: Path, progress_window):
        """加载临时PDF并显示预览"""
        try:
            # 关闭进度窗口
            progress_window.destroy()

            # 更新状态显示
            self.status_label.config(text="正在生成预览...")
            self.root.update()

            # 使用PDF处理器加载临时PDF
            success = self.pdf_processor.load_document(str(temp_pdf_path))
            if not success:
                raise Exception("临时PDF加载失败")

            # 生成缩略图（复用现有的PDF缩略图生成逻辑）
            self._generate_thumbnails_sync()

            # 更新状态
            self.current_ppt_path = ppt_path
            self.current_pdf_path = None  # 不设置为临时PDF路径
            self.temp_pdf_path = temp_pdf_path  # 保存临时PDF路径用于清理
            self.current_file_type = 'ppt'

            filename = Path(ppt_path).name
            self.status_label.config(text=f"已加载PPT预览: {filename}")
            self.page_info_label.config(text=f"共 {self.pdf_processor.page_count} 张幻灯片")

            self.logger.info(f"PPT预览加载完成: {self.pdf_processor.page_count} 张幻灯片")

        except Exception as e:
            self.logger.error(f"PPT预览加载失败: {e}")
            messagebox.showerror("错误", f"PPT预览加载失败:\n{e}")
            self.status_label.config(text="预览加载失败")

            # 清理临时文件
            if temp_pdf_path:
                self.ppt_converter.cleanup_temp_pdf(temp_pdf_path)

    def _handle_ppt_preview_error(self, error: str, progress_window):
        """处理PPT预览错误"""
        # 关闭进度窗口
        progress_window.destroy()

        self.logger.error(f"PPT预览失败: {error}")
        messagebox.showerror("预览失败", f"PPT预览失败:\n{error}")
        self.status_label.config(text="预览失败")

    def _cleanup_temp_files(self):
        """清理临时文件"""
        if hasattr(self, 'temp_pdf_path') and self.temp_pdf_path:
            try:
                self.ppt_converter.cleanup_temp_pdf(self.temp_pdf_path)
                self.temp_pdf_path = None
            except Exception as e:
                self.logger.warning(f"清理临时文件失败: {e}")



    def _on_ppt_converted(self, output_path):
        """PPT转换完成回调"""
        self.root.after(0, lambda: self._handle_ppt_converted(output_path))

    def _handle_ppt_converted(self, output_path):
        """处理PPT转换完成"""
        # 关闭进度对话框
        if hasattr(self, '_current_progress'):
            self._current_progress.close()

        self.logger.info(f"PPT转换完成: {output_path}")
        messagebox.showinfo("转换成功", f"文件已成功转换至:\n{output_path}")

        # 询问是否打开转换后的PDF
        if messagebox.askyesno("打开文件", "是否要打开转换后的PDF文件？"):
            self._load_converted_pdf(str(output_path))

    def _on_ppt_convert_error(self, error):
        """PPT转换错误回调"""
        self.root.after(0, lambda: self._handle_ppt_convert_error(error))

    def _handle_ppt_convert_error(self, error):
        """处理PPT转换错误"""
        # 关闭进度对话框
        if hasattr(self, '_current_progress'):
            self._current_progress.close()

        self.logger.error(f"PPT转换失败: {error}")
        messagebox.showerror("转换失败", f"PPT转换失败:\n{error}")

    def _load_converted_pdf(self, file_path: str):
        """加载转换后的PDF"""
        task = Task(
            func=self._load_pdf_async,
            args=(file_path,),
            callback=self._on_pdf_loaded,
            error_callback=self._on_pdf_load_error
        )

        self.async_processor.submit_task(task)

        progress = ProgressDialog(self.root, "加载PDF", "正在加载转换后的PDF...")
        progress.show()
        progress.set_indeterminate(True)
        self._current_progress = progress

    def _select_all(self):
        """全选页面"""
        if not self.current_pdf_path and not self.current_ppt_path:
            messagebox.showinfo("提示", "请先打开PDF或PPT文件")
            return

        self.thumbnail_viewer.select_all()

    def _invert_selection(self):
        """反选页面"""
        if not self.current_pdf_path and not self.current_ppt_path:
            messagebox.showinfo("提示", "请先打开PDF或PPT文件")
            return

        self.thumbnail_viewer.invert_selection()

    def _clear_selection(self):
        """清除选择"""
        if not self.current_pdf_path and not self.current_ppt_path:
            messagebox.showinfo("提示", "请先打开PDF或PPT文件")
            return

        self.thumbnail_viewer.select_none()

    def _export_merged(self):
        """合并导出选中页面，支持PDF和PPT"""
        if not self.current_pdf_path and not self.current_ppt_path:
            messagebox.showinfo("提示", "请先打开PDF或PPT文件")
            return

        if not self.selected_pages:
            messagebox.showwarning("警告", "请至少选择一页")
            return

        # 选择保存路径
        save_path = filedialog.asksaveasfilename(
            title="保存合并的PDF",
            defaultextension=".pdf",
            filetypes=[("PDF文件", "*.pdf"), ("所有文件", "*.*")]
        )

        if not save_path:
            return

        # 参考原始实现：在工具栏添加进度条
        try:
            progress = ttk.Progressbar(self.toolbar_frame, orient=tk.HORIZONTAL, maximum=1)
            progress.pack(side=tk.RIGHT, padx=10, fill=tk.X, expand=True)
            progress['value'] = 0
            self.root.update()

            if self.current_file_type == 'pdf':
                # PDF导出
                self.pdf_processor.extract_pages(list(self.selected_pages), save_path)
            elif self.current_file_type == 'ppt':
                # PPT预览导出：直接从临时PDF中提取页面（高质量）
                if hasattr(self, 'temp_pdf_path') and self.temp_pdf_path and self.temp_pdf_path.exists():
                    # 使用临时PDF进行页面提取（保持原始质量）
                    self.pdf_processor.extract_pages(list(self.selected_pages), save_path)
                else:
                    # 备用方案：重新转换PPT（不应该发生）
                    raise Exception("临时PDF文件不存在，无法导出")

            progress['value'] = 1
            self.root.update()

            self.logger.info(f"合并导出完成: {save_path}")
            messagebox.showinfo("导出成功", f"合并导出完成!\n文件保存至: {save_path}")

        except Exception as e:
            self.logger.error(f"合并导出失败: {e}")
            messagebox.showerror("导出失败", f"导出过程中发生错误:\n{e}")
        finally:
            try:
                progress.destroy()
            except:
                pass

    def _export_separate(self):
        """分页导出选中页面，支持PDF和PPT"""
        if not self.current_pdf_path and not self.current_ppt_path:
            messagebox.showinfo("提示", "请先打开PDF或PPT文件")
            return

        if not self.selected_pages:
            messagebox.showwarning("警告", "请至少选择一页")
            return

        # 选择输出目录
        output_dir = filedialog.askdirectory(title="选择输出目录")
        if not output_dir:
            return

        # 参考原始实现：在工具栏添加进度条
        try:
            progress = ttk.Progressbar(self.toolbar_frame, orient=tk.HORIZONTAL, maximum=len(self.selected_pages))
            progress.pack(side=tk.RIGHT, padx=10, fill=tk.X, expand=True)
            self.root.update()

            if self.current_file_type == 'pdf':
                # PDF分页导出
                file_list = self.pdf_processor.extract_pages_separately(
                    list(self.selected_pages),
                    output_dir,
                    progress_callback=lambda current, total: self._update_progress_bar(progress, current, total)
                )
                self.logger.info(f"PDF分页导出完成: {len(file_list)} 个文件")
                messagebox.showinfo("导出成功", f"分页导出完成!\n成功创建 {len(file_list)} 个文件")

            elif self.current_file_type == 'ppt':
                # PPT预览分页导出：直接从临时PDF中分页提取（高质量）
                if hasattr(self, 'temp_pdf_path') and self.temp_pdf_path and self.temp_pdf_path.exists():
                    # 使用临时PDF进行分页提取（保持原始质量）
                    file_list = self.pdf_processor.extract_pages_separately(
                        list(self.selected_pages),
                        output_dir,
                        progress_callback=lambda current, total: self._update_progress_bar(progress, current, total)
                    )
                    self.logger.info(f"PPT预览分页导出完成: {len(file_list)} 个文件")
                    messagebox.showinfo("导出成功", f"分页导出完成!\n成功创建 {len(file_list)} 个文件")
                else:
                    # 备用方案：重新转换PPT（不应该发生）
                    raise Exception("临时PDF文件不存在，无法导出")

        except Exception as e:
            self.logger.error(f"分页导出失败: {e}")
            messagebox.showerror("导出失败", f"导出过程中发生错误:\n{e}")
        finally:
            try:
                progress.destroy()
            except:
                pass

    def _update_progress_bar(self, progress_bar, current, total):
        """更新进度条"""
        try:
            progress_bar['value'] = current
            self.root.update()
        except:
            pass



    def _on_closing(self):
        """处理窗口关闭"""
        try:
            # 清理临时文件
            self._cleanup_temp_files()

            # 保存配置
            if self.config.processing.auto_save_config:
                self.config.save_config()

            # 关闭异步处理器
            self.async_processor.shutdown(wait=False)

            # 关闭PDF处理器
            self.pdf_processor.close_document()

            self.logger.info("应用程序正常退出")

        except Exception as e:
            self.logger.error(f"退出时发生错误: {e}")
        finally:
            self.root.destroy()

    def run(self):
        """运行应用程序"""
        try:
            self.root.mainloop()
        except KeyboardInterrupt:
            self.logger.info("用户中断程序")
        except Exception as e:
            self.logger.error(f"程序运行时发生错误: {e}", exc_info=True)
            messagebox.showerror("严重错误", f"程序发生严重错误:\n{e}")
        finally:
            self._on_closing()
